{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "77a24060-17cc-4526-be70-1d165cd8db21",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<torch._C.Generator at 0x1d5d2ce22f0>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "torch.manual_seed(1024)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c55bbb22-2b8f-42a4-9865-cba76a85eaf7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义线性模型和Sigmoid函数\n",
    "class Linear:\n",
    "    # input :(B, in_features)\n",
    "    # output (B, out_features)\n",
    "\n",
    "    def __init__(self,in_features,out_features,bias=False):\n",
    "        self.weight = torch.randn(in_features,out_features,requires_grad = True)\n",
    "        if bias:\n",
    "            self.bias = torch.randn(out_features,requires_grad = True)\n",
    "        else :\n",
    "            self.bias = None\n",
    "\n",
    "    def __call__(self,x):\n",
    "        # x :(B, in_features)\n",
    "        #self.weight (in_features, out_features)\n",
    "        self.out = x @ self.weight \n",
    "        if self.bias is not None:\n",
    "            self.out += self.bias\n",
    "        return self.out\n",
    "\n",
    "    def parameters(self):\n",
    "        # 返回模型参数\n",
    "        if self.bias is not None:\n",
    "            return [self.weight,self.bias]\n",
    "        return [self.weight]\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "cab9420c-8a1a-414b-b0d8-23527237f155",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0.8725, -1.3424,  1.7336,  0.3008],\n",
       "        [ 1.2790, -0.4374,  1.9408,  0.5689],\n",
       "        [-0.8642, -0.0465, -0.7873,  0.2805],\n",
       "        [ 4.1653, -1.4934,  5.5663,  0.4573],\n",
       "        [-1.5655, -0.3404, -1.8207, -0.3939]], grad_fn=<MmBackward0>)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mod = Linear(3,4)\n",
    "x = torch.randn(5,3)\n",
    "mod(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "603baf53-e141-4087-b662-8a4a3dafdaac",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Sigmoid:\n",
    "\n",
    "    def __call__(self,x):\n",
    "        self.out = torch.sigmoid(x)\n",
    "        return self.out\n",
    "    def parameters(self):\n",
    "        return []\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "0c051e55-315c-47ab-b9c8-6c29b9f9c589",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.1854, 0.2970],\n",
       "        [0.2853, 0.4911],\n",
       "        [0.6022, 0.6637]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = Sigmoid()\n",
    "x = torch.randn(3,2)\n",
    "s(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "633f56f0-5659-4762-b2cd-da2a667fb45b",
   "metadata": {},
   "source": [
    "## 将Sigmoid激活层和Linear线性层放到一个Perception层中"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "0bde412e-4dd9-468a-be49-3483d7d697f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Perception:\n",
    "    def __init__(self,in_features):\n",
    "        self.ln = Linear(in_features,1)\n",
    "        self.f = Sigmoid()\n",
    "\n",
    "    def __call__(self,x):\n",
    "        # x (B ,in_features)\n",
    "        self.out = self.f(self.ln(x)) # (B,1)\n",
    "        return self.out\n",
    "\n",
    "    def parameters(self):\n",
    "        return self.ln.parameters() + self.f.parameters()\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "42066667-b08e-4349-9a68-7778bdc9ba88",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.9709],\n",
       "        [0.8771],\n",
       "        [0.0031],\n",
       "        [0.7788],\n",
       "        [0.3501]], grad_fn=<SigmoidBackward0>)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p = Perception(3)\n",
    "x = torch.randn(5,3)\n",
    "p(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3052f946-75ec-4cbc-81a3-8cdb5b9babf3",
   "metadata": {},
   "source": [
    "## 对于上面的Perception类进行修改,让其变成二分类问题"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "63353f53-39c0-43bf-b41f-c2bea2d60ac5",
   "metadata": {},
   "outputs": [],
   "source": [
    "class LogitRegression:\n",
    "    # input : (B, in_features)\n",
    "    # output :(B, 2)\n",
    "    def __init__(self,in_features):\n",
    "        self.pos = Linear(in_features,1)\n",
    "        self.neg = Linear(in_features,1)\n",
    "\n",
    "    def __call__(self,x):\n",
    "        # x (B ,in_features)\n",
    "        self.out = torch.concat((self.pos(x),self.neg(x)),dim = -1) # (B,2)\n",
    "        return self.out\n",
    "    def parameters(self):\n",
    "        return self.pos.parameters() + self.neg.parameters()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "07bc3ead-49fc-4177-a26b-72d7067828b0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 1.6791, -0.9622],\n",
      "        [ 3.4948, -0.0384],\n",
      "        [-2.5182, -0.9839],\n",
      "        [-1.3661,  1.1890],\n",
      "        [-1.6569, -0.8481],\n",
      "        [-0.3405, -0.9584],\n",
      "        [ 3.6480,  3.1088],\n",
      "        [ 2.5640,  3.0726],\n",
      "        [ 1.5174,  1.3484],\n",
      "        [-2.4035, -6.4298],\n",
      "        [-0.6344, -3.6559],\n",
      "        [-1.4856, -0.5830]], grad_fn=<CatBackward0>)\n"
     ]
    }
   ],
   "source": [
    "lr = LogitRegression(3)\n",
    "x = torch.randn(12,3)\n",
    "logits = lr(x)\n",
    "print(logits)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9bf416d2-27e9-42a6-8751-2b8d14c011a0",
   "metadata": {},
   "source": [
    "## 将二维的输入经过softmax变换后输出"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "4b2d5cda-e5d8-4ce7-abda-4d4a4dda6c29",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 1.6791, -0.9622],\n",
      "        [ 3.4948, -0.0384],\n",
      "        [-2.5182, -0.9839],\n",
      "        [-1.3661,  1.1890],\n",
      "        [-1.6569, -0.8481],\n",
      "        [-0.3405, -0.9584],\n",
      "        [ 3.6480,  3.1088],\n",
      "        [ 2.5640,  3.0726],\n",
      "        [ 1.5174,  1.3484],\n",
      "        [-2.4035, -6.4298],\n",
      "        [-0.6344, -3.6559],\n",
      "        [-1.4856, -0.5830]], grad_fn=<CatBackward0>)\n"
     ]
    }
   ],
   "source": [
    "import torch.nn.functional as F\n",
    "F.softmax(logits,dim = -1)\n",
    "print(logits)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3b8582ca-1dc9-4750-9019-4672ac694a62",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8bdf4d85-026c-4740-a12d-cddac1d47286",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f79c4df2-0e08-4408-b08b-bbaafcd284dc",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a19e53f8-08b1-4c8e-8c6b-a2ba4cda8547",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "debf2206-70c3-4bf6-a2c3-927a4afeedb3",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "45e17ce1-70e3-46ad-9a0f-3e9729e7050a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
